package me.guowenlong.rxextension.api;

import android.support.annotation.NonNull;

import com.google.gson.GsonBuilder;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import retrofit2.CallAdapter;
import retrofit2.Converter;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;


/**
 * desc   : Retrofit和okhttp的简单封装
 * author : guowenlong
 * Email  : guowenlong20000@gmail.com
 */
public class RetrofitHelper {
    private Retrofit mRetrofit;

    public static class Builder {
        private String mBaseUrl;
        private long mReadTimeout;
        private long mConnectTimeout;
        private boolean isRelease;
        private TimeUnit mTimeUnit;
        private List<Interceptor> mInterceptors;
        private Converter.Factory mConverter;
        private CallAdapter.Factory mCallAdapter;

        public Builder() {
            this.mReadTimeout = 10_000;
            this.mConnectTimeout = 10_000;
            this.isRelease = false;
            this.mTimeUnit = TimeUnit.MILLISECONDS;
            this.mInterceptors = new ArrayList<>();
            this.mConverter = GsonConverterFactory.create(new GsonBuilder().setLenient().create());
            this.mCallAdapter = RxJava2CallAdapterFactory.create();
        }

        public Builder setBaseUrl(@NonNull String baseUrl) {
            this.mBaseUrl = baseUrl;
            return this;
        }

        public Builder setRelease(boolean release) {
            isRelease = release;
            return this;
        }

        public Builder setReadTimeout(long readTimeout) {
            this.mReadTimeout = readTimeout;
            return this;
        }

        public Builder setConnectTimeout(long connectTimeout) {
            this.mConnectTimeout = connectTimeout;
            return this;
        }

        public Builder setTimeUnit(TimeUnit timeUnit) {
            this.mTimeUnit = timeUnit;
            return this;
        }

        public Builder addInterceptor(Interceptor interceptor) {
            mInterceptors.add(interceptor);
            return this;
        }

        public void setConverter(Converter.Factory mConverter) {
            this.mConverter = mConverter;
        }

        public void setCallAdapter(CallAdapter.Factory mCallAdapter) {
            this.mCallAdapter = mCallAdapter;
        }

        public RetrofitHelper build() {
            return new RetrofitHelper(this);
        }
    }

    private RetrofitHelper(Builder builder) {
        mRetrofit = new Retrofit.Builder()
                .client(getOkHttpClientBuilder(builder).build())
                .addConverterFactory(builder.mConverter)
                .addCallAdapterFactory(builder.mCallAdapter)
                .baseUrl(builder.mBaseUrl)
                .build();
    }

    private OkHttpClient.Builder getOkHttpClientBuilder(Builder builder) {
        OkHttpClient.Builder okBuilder = new OkHttpClient.Builder()
                .readTimeout(builder.mReadTimeout, builder.mTimeUnit)
                .connectTimeout(builder.mConnectTimeout, builder.mTimeUnit);

        if (builder.mInterceptors != null) {
            for (Interceptor interceptor : builder.mInterceptors) {
                okBuilder.addInterceptor(interceptor);
            }
        }
        return okBuilder;
    }

    public <T> T create(final Class<T> service) {
        return mRetrofit.create(service);
    }
}